package com.yilin.platform.controller.user;

import cn.hutool.core.util.CreditCodeUtil;
import cn.hutool.core.util.IdcardUtil;
import com.yilin.platform.base_core.application.BaseController;
import com.yilin.platform.base_core.application.PageData;
import com.yilin.platform.base_core.application.ReturnData;
import com.yilin.platform.base_core.commons.annotation.Explain;
import com.yilin.platform.base_core.commons.annotation.NotNull;
import com.yilin.platform.base_core.commons.base.BaseAuth;
import com.yilin.platform.base_core.commons.entity.AuthData;
import com.yilin.platform.base_core.commons.entity.AuthStatus;
import com.yilin.platform.base_core.commons.utils.DateTimeUtil;
import com.yilin.platform.base_core.commons.utils.ParamUtil;
import com.yilin.platform.base_core.commons.utils.StringUtil;
import com.yilin.platform.entity.user.Account;
import com.yilin.platform.entity.user.auth.*;
import com.yilin.platform.service.user.IAccountService;
import com.yilin.platform.service.user.IAuthService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 认证控制器
 *
 * @author zhangjinyuan
 * @date 2022/10/26
 */
@RestController
@RequestMapping("/user/auth/")
public class AuthController extends BaseController {

    @Resource
    IAuthService authService;
    @Resource
    IAccountService userAccountService;

    /**
     * APP-获取用户认证数据
     *
     * @param accountId 用户ID，为空时查询当前登录用户认证数据
     */
    @PostMapping(value = "getUserAuthData")
    public ReturnData<List<AuthData>> getUserAuthData(String accountId) {
        Account loginUser = getLoginUser();
        if (StringUtil.isNotEmpty(accountId)) loginUser =  userAccountService.getById(accountId);
        List<AuthData> authOption = authService.getUserAuthData(loginUser);
        return jsonView(true, "获取用户认证许可成功！", authOption);
    }

    /**
     * 微服务/APP-校验认证
     */
    @PostMapping(value = "checkAuthStatus")
    public ReturnData<Object> checkAuthStatus(String accountId, AuthData.AuthItem[] authItems) {
        Account account = getLoginUser();
        if (accountId!=null) account = userAccountService.getAccountById(accountId);
        for (AuthData.AuthItem authItem : authItems) {
            authService.checkAuthStatus(account,getLoginUser()==null?account:getLoginUser(), authItem);
        }
        return jsonView(true, "认证校验成功！");
    }

    //-----分页区 已修改：接口拆分，方便做权限，比如哪些用户只能查看哪些证件

    /**
     * 分页区：获取身份证认证分页
     */
    @PostMapping(value = "getIdCardAuthPage")
    @NotNull({"page", "limit"})
    public ReturnData<PageData<? extends BaseAuth>> getIdCardAuthPage(IdCard query, @Explain("页码") Integer page, @Explain("条数") Integer limit) {
        PageData<? extends BaseAuth> pageData = authService.getAuthPage(getLoginUser(), AuthData.AuthItem.authIdCard, query, page, limit);
        return jsonView(true, "获取认证成功！", pageData);
    }

    /**
     * 分页区：获取营业执照认证分页
     */
    @PostMapping(value = "getBusinessLicenseAuthPage")
    @NotNull({"page", "limit"})
    public ReturnData<PageData<? extends BaseAuth>> getBusinessLicenseAuthPage(BusinessLicense query, @Explain("页码") Integer page, @Explain("条数") Integer limit) {
        PageData<? extends BaseAuth> pageData = authService.getAuthPage(getLoginUser(), AuthData.AuthItem.authBusinessLicense, query, page, limit);
        return jsonView(true, "获取认证成功！", pageData);
    }

    /**
     * 分页区：获取驾驶证认证分页
     */
    @PostMapping(value = "getDrivingLicenseAuthPage")
    @NotNull({"page", "limit"})
    public ReturnData<PageData<? extends BaseAuth>> getDrivingLicenseAuthPage(DrivingLicense query, @Explain("页码") Integer page, @Explain("条数") Integer limit) {
        PageData<? extends BaseAuth> pageData = authService.getAuthPage(getLoginUser(), AuthData.AuthItem.authDrivingLicense, query, page, limit);
        return jsonView(true, "获取认证成功！", pageData);
    }

    /**
     * 分页区：获取道路运输许可认证分页
     */
    @PostMapping(value = "geTransBusinessLicenseAuthPage")
    @NotNull({"page", "limit"})
    public ReturnData<PageData<? extends BaseAuth>> geTransBusinessLicenseAuthPage(TransBusinessLicense query, @Explain("页码") Integer page, @Explain("条数") Integer limit) {
        PageData<? extends BaseAuth> pageData = authService.getAuthPage(getLoginUser(), AuthData.AuthItem.authTransBusinessLicense, query, page, limit);
        return jsonView(true, "获取认证成功！", pageData);
    }

    /**
     * 分页区：获取从业资格证认证分页
     */
    @PostMapping(value = "getQualificationCertAuthPage")
    @NotNull({"page", "limit"})
    public ReturnData<PageData<? extends BaseAuth>> getQualificationCertAuthPage(QualificationCert query, @Explain("页码") Integer page, @Explain("条数") Integer limit) {
        PageData<? extends BaseAuth> pageData = authService.getAuthPage(getLoginUser(), AuthData.AuthItem.authQualificationCert, query, page, limit);
        return jsonView(true, "获取认证成功！", pageData);
    }

    /**

    //---获取详情区

    /**
     * 获取用户身份证 详情
     */
    @PostMapping(value = "getIdCardByUserId")
    public ReturnData<IdCard> getIdCardByUserId(@Explain("用户ID") String accountId) {
        if(StringUtil.isEmpty(accountId))accountId= getLoginUser().getId();
        IdCard idCard = authService.getIdCardByUserId(accountId);
//        ParamUtil.platformCheck(idCard, getLoginUser());
        return jsonView(true, "获取用户身份证成功！", idCard);
    }

    /**
     * 根据身份证号获取用户身份证 详情
     */
    @PostMapping(value = "getIdCardByIdCardNo")
    @NotNull({"idCardNo"})
    public ReturnData<IdCard> getIdCardByIdCardNo(@Explain("身份证号") String idCardNo) {
        IdCard idCard = authService.getIdCardByIdCardNo(idCardNo);
        //ParamUtil.platformCheck(idCard, getLoginUser());
        return jsonView(true, "获取用户身份证成功！", idCard);
    }

    /**
     * 获取驾驶证 详情
     */
    @PostMapping(value = "getDrivingLicenseByUserId")
    public ReturnData<DrivingLicense> getDrivingLicenseByUserId(@Explain("用户ID") String accountId) {
        if(StringUtil.isEmpty(accountId))accountId= getLoginUser().getId();
        DrivingLicense drivingLicense = authService.getDrivingLicenseByUserId(accountId);
//        ParamUtil.platformCheck(drivingLicense, getLoginUser());
        return jsonView(true, "获取驾驶证成功！", drivingLicense);
    }

    /**
     * 获取从业资格证 详情
     */
    @PostMapping(value = "getQualificationCertByUserId")
    public ReturnData<QualificationCert> getQualificationCertByUserId(@Explain("用户ID") String accountId) {
        if(StringUtil.isEmpty(accountId))accountId= getLoginUser().getId();;
        QualificationCert qualificationCert = authService.getQualificationCertByUserId(accountId);
//        ParamUtil.platformCheck(qualificationCert, getLoginUser());
        return jsonView(true, "获取从业资格证成功！", qualificationCert);
    }

    /**
     * 获取营业执照 详情
     */
    @PostMapping(value = "getBusinessLicenseByOrganizeId")
    public ReturnData<BusinessLicense> getBusinessLicenseByOrganizeId(String organizeId) {
        if(StringUtil.isEmpty(organizeId))organizeId= getLoginUser().getOrganizeId();
        BusinessLicense businessLicense = authService.getBusinessLicenseByOrganizeId(organizeId);
        //ParamUtil.platformCheck(businessLicense, getLoginUser());
        return jsonView(true, "获取营业执照成功！", businessLicense);
    }

    /**
     * 获取道路经营许可证 详情
     */
    @PostMapping(value = "getTransLicenseByOrganizeId")
    public ReturnData<TransBusinessLicense> getTransLicenseByOrganizeId(@Explain("组织ID") String organizeId) {
        if(StringUtil.isEmpty(organizeId))organizeId= getLoginUser().getOrganizeId();
        TransBusinessLicense transBusinessLicense = authService.getTransLicenseByOrganizeId(organizeId);
//        ParamUtil.platformCheck(transBusinessLicense, getLoginUser());
        return jsonView(true, "获取道路经营许可证成功！", transBusinessLicense);
    }

    /**


    //--存储写入区

    /**
     * 保存和修改身份证
     */
    @PostMapping(value = "saveIdCardAuth")
    @NotNull({"idCardFrontImg", "idCardBackImg", "idCardNo", "startTime", "endTime", "idCardPersonImg"})
    public ReturnData<Object> saveIdCardAuth(IdCard idCard) {
        if (!IdcardUtil.isValidCard(idCard.getIdCardNo())) {
            return jsonView(false, "身份证格式错误，请仔细核对！");
        }
        if (idCard.getStartTime().compareTo(new Date()) > 0) {
            return jsonView(false, "身份证生效日期错误，请仔细核对！");
        }
        if (idCard.getEndTime().compareTo(new Date()) < 0) {
            return jsonView(false, "身份证已过期，请仔细核对！");
        }
        IdCard local = authService.getIdCardByUserId(getLoginUser().getId());
        if (local!=null && local.getAuthStatus()== AuthStatus.authSuccess && !idCard.getIdCardNo().equals(local.getIdCardNo())) {
            return jsonView(false, "您的身份证已认证成功，禁止修改证件号！");
        }
        idCard.setBirthday(DateTimeUtil.stringToDate(idCard.getIdCardNo().substring(6, 14), "yyyyMMdd"));
        authService.saveIdCardAuth(getLoginUser(), idCard);
        return jsonView(true, "保存身份证成功！");
    }

    /**
     * 保存和修改营业执照
     */
    @PostMapping(value = "saveBusinessLicenseAuth")
    @NotNull({"companyImg", "legalIdCardFontImg", "businessNo", "validityEndDate", "bcValidityEndDate"})
    public ReturnData<Object> saveBusinessLicenseAuth(BusinessLicense businessLicense) {
        if (businessLicense.getBusinessNo().trim().length() < 15 || businessLicense.getBusinessNo().trim().length() > 18) {
            return jsonView(false, "营业执照编号错误，请仔细核对！");
        }
        IdCard idCard = authService.getIdCardByUserId(getLoginUser().getId());
        ParamUtil.isNull(idCard, "您还没有认证身份证，请先认证身份证");
        if (!CreditCodeUtil.isCreditCode(businessLicense.getBusinessNo())) {
            return jsonView(false, "营业执照格式错误，请仔细核对！");
        }
        if (businessLicense.getValidityEndDate().compareTo(new Date()) < 0) {
            return jsonView(false, "营业执照已过期，请仔细核对！");
        }
        if (businessLicense.getBcValidityEndDate().compareTo(new Date()) < 0) {
            return jsonView(false, "法人身份证已过期，请仔细核对！");
        }
        BusinessLicense local = authService.getBusinessLicenseByOrganizeId(getLoginUser().getOrganizeId());
        if (local!=null && local.getAuthStatus()==AuthStatus.authSuccess && !businessLicense.getBusinessNo().equals(local.getBusinessNo())) {
            return jsonView(false, "您的营业执照已认证成功，禁止修改证件号！");
        }
        authService.saveBusinessLicenseAuth(getLoginUser(), businessLicense);
        return jsonView(true, "保存营业执照成功！");
    }

    /**
     * 保存和修改道路运输经营许可证
     */
    @PostMapping(value = "saveTransBusinessLicenseAuth")
    @NotNull({"transBusinessLicenseImg", "transBusinessLicenseNo", "transBusinessLicenseEndDate", "transBusinessLicenseScope"})
    public ReturnData<Object> saveTransBusinessLicenseAuth(TransBusinessLicense transBusinessLicense) {
        if ((transBusinessLicense.getTransBusinessLicenseEndDate().compareTo(new Date())) < 0) {
            return jsonView(false, "道路运输经营许可证已过期，请仔细核对！");
        }
        IdCard idCard = authService.getIdCardByUserId(getLoginUser().getId());
        ParamUtil.isNull(idCard, "您还没有认证身份证，请先认证身份证");
        BusinessLicense businessLicense = authService.getBusinessLicenseByOrganizeId(getLoginUser().getOrganizeId());
        if (businessLicense == null) return jsonErrView("您好！请先提交营业执照！");
        authService.saveTransBusinessLicenseAuth(getLoginUser(), transBusinessLicense);
        return jsonView(true, "保存道路运输经营许可证成功！");
    }

    /**
     * 保存和修改驾驶证
     */
    @PostMapping(value = "saveDrivingLicenseAuth")
    @NotNull({"drivingLicenseImg", "validStartDate", "validEndDate", "drivingLicenseName", "drivingLicenseNo", "issuingOrganizations", "drivingLicenseType"})
    public ReturnData<Object> saveDrivingLicenseAuth(DrivingLicense drivingLicense) {
        if ((drivingLicense.getValidStartDate().compareTo(new Date())) > 0) {
            return jsonView(false, "驾驶证生效时间错误，请仔细核对！");
        }
        if ((drivingLicense.getValidEndDate().compareTo(new Date())) < 0) {
            return jsonView(false, "驾驶证已过期，请仔细核对！");
        }
        IdCard idCard = authService.getIdCardByUserId(getLoginUser().getId());
        if (idCard == null) return jsonErrView("您好！请先提交身份证！");
        if (!drivingLicense.getDrivingLicenseNo().equals(idCard.getIdCardNo())){
            return jsonView(false, "您好，您的驾驶证与身份证信息不匹配，请重新上传驾驶证！");
        }
        if (!drivingLicense.getDrivingLicenseName().equals(idCard.getName())){
            return jsonView(false, "您好，您的驾驶证与身份证信息不匹配，请重新上传驾驶证！");
        }
        authService.saveDrivingLicenseAuth(getLoginUser(), drivingLicense);
        return jsonView(true, "保存驾驶证成功！");
    }

    /**
     * 保存和修改从业资格证
     */
    @PostMapping(value = "saveQualificationCertAuth")
    @NotNull({"qualificationPhotoImg", "qualificationEndDate", "occupationalRequirementsNo", "qualificationCategories", "qualificationArea"})
    public ReturnData<Object> saveQualificationCertAuth(QualificationCert qualificationCert) {
        if ((qualificationCert.getQualificationEndDate().compareTo(new Date())) < 0) {
            return jsonView(false, "从业资格证已过期，请仔细核对！");
        }
        IdCard idCard = authService.getIdCardByUserId(getLoginUser().getId());
        if (idCard == null) return jsonErrView("您好！请先提交身份证！");
        if (!qualificationCert.getOccupationalRequirementsNo().equals(idCard.getIdCardNo())){
            return jsonView(false, "您好，您的从业资格证与身份证信息不匹配，请重新上传从业资格证！");
        }
        authService.saveQualificationCertAuth(getLoginUser(), qualificationCert);
        return jsonView(true, "保存从业资格证成功！");
    }




    //-----审核区-----

    /**
     * 审核并更新身份证数据
     */
    @PostMapping(value = "verifyIdCard")
    @NotNull({"idCardFrontImg", "idCardBackImg", "idCardNo", "startTime", "endTime", "idCardPersonImg"})
    public ReturnData<Object> verifyIdCard(IdCard idCard) {
        if (!IdcardUtil.isValidCard(idCard.getIdCardNo())) {
            return jsonView(false, "身份证格式错误，请仔细核对！");
        }
        if (idCard.getStartTime().compareTo(new Date()) > 0) {
            return jsonView(FAIL_CODE, "请核对身份证生效日期！");
        }
        if (idCard.getEndTime().compareTo(new Date()) < 0) {
            return jsonView(FAIL_CODE, "请核对身份证失效日期或检查身份证是否过期！");
        }
        authService.verifyAndUpdateAuth(idCard, getLoginUser());
        return jsonView(SUCCESS_CODE, "身份证信息更新成功！");
    }

    /**
     * 审核并更新驾驶证数据
     */
    @PostMapping(value = "verifyDrivingLicense")
    @NotNull({"accountId", "drivingLicenseImg", "validStartDate", "validEndDate", "drivingLicenseName", "drivingLicenseNo", "issuingOrganizations", "drivingLicenseType"})
    public ReturnData<Object> verifyDrivingLicense(DrivingLicense drivingLicense) {
        IdCard idCard = authService.getIdCardByUserId(drivingLicense.getAccountId());
        if (idCard == null || idCard.getAuthStatus() != AuthStatus.authSuccess) {
            return jsonView(FAIL_CODE, "请先审核身份证，身份证通过后才能审核驾驶证！");
        }
        authService.verifyAndUpdateAuth(drivingLicense, getLoginUser());
        return jsonView(SUCCESS_CODE, "驾驶证信息更新成功！");
    }

    /**
     * 审核并更新从业资格证数据
     */
    @PostMapping(value = "verifyQualificationCert")
    @NotNull({"qualificationPhotoImg", "qualificationEndDate", "occupationalRequirementsNo", "qualificationCategories", "qualificationArea"})
    public ReturnData<Object> verifyQualificationCert(QualificationCert qualificationCert) {
        IdCard idCard = authService.getIdCardByUserId(qualificationCert.getAccountId());
        if (idCard == null || idCard.getAuthStatus() != AuthStatus.authSuccess) {
            return jsonView(FAIL_CODE, "请先审核身份证，身份证通过后才能审核从业资格证！");
        }
        authService.verifyAndUpdateAuth(qualificationCert, getLoginUser());
        return jsonView(SUCCESS_CODE, "从业资格证信息更新成功！");
    }

    /**
     * 审核并更新营业执照数据
     */
    @PostMapping(value = "verifyBusinessLicense")
    @NotNull({"companyImg", "legalIdCardFontImg", "businessNo", "validityStartDate", "validityEndDate", "bcValidityStartDate", "bcValidityEndDate"})
    public ReturnData<Object> verifyBusinessLicense(BusinessLicense businessLicense) {
        if (businessLicense.getBusinessNo().trim().length() < 15) {
            return jsonView(false, "营业执照长度错误，请仔细核对！");
        }
        if (businessLicense.getBusinessNo().trim().length() > 18) {
            return jsonView(false, "营业执照长度错误，请仔细核对！");
        }
        Date getBcValidityStartDate = businessLicense.getBcValidityStartDate();
        Date getBcValidityEndDate = businessLicense.getBcValidityEndDate();
        Date getValidityStartDate = businessLicense.getValidityStartDate();
        Date getValidityEndDate = businessLicense.getValidityEndDate();
        if (getBcValidityStartDate != null) {
            if (getBcValidityStartDate.getTime() > new Date().getTime() ||
                    businessLicense.getBcValidityStartDate() == null) {
                return jsonView(FAIL_CODE, "请核对法人身份证生效日期！");
            }
        }
        if (getBcValidityEndDate != null) {
            if (getBcValidityEndDate.getTime() <= new Date().getTime() ||
                    businessLicense.getBcValidityEndDate() == null) {
                return jsonView(FAIL_CODE, "请核对法人身份证失效日期或检查法人身份证是否过期！");
            }
        }
        if (getValidityStartDate != null) {
            if (getValidityStartDate.getTime() > new Date().getTime() ||
                    businessLicense.getValidityStartDate() == null) {
                return jsonView(FAIL_CODE, "请核对营业执照生效日期！");
            }
        }
        if (getValidityEndDate != null) {
            if (getValidityEndDate.getTime() <= new Date().getTime() ||
                    businessLicense.getValidityEndDate() == null) {
                return jsonView(FAIL_CODE, "请核对营业执照失效日期或检查营业执照是否过期！");
            }
        }
        authService.verifyAndUpdateAuth(businessLicense, getLoginUser());
        return jsonView(SUCCESS_CODE, "营业执照信息更新成功！");
    }

    /**
     * 审核并更新道路运输经营许可证数据
     */
    @PostMapping(value = "verifyTransBusinessLicense")
    @NotNull({"transBusinessLicenseImg", "transBusinessLicenseEndDate", "transBusinessLicenseScope", "organizeId"})
    public ReturnData<Object> verifyTransBusinessLicense(TransBusinessLicense transBusinessLicense) {
        BusinessLicense businessLicense = authService.getBusinessLicenseByOrganizeId(transBusinessLicense.getOrganizeId());
        if (businessLicense == null || businessLicense.getAuthStatus() != AuthStatus.authSuccess) {
            return jsonView(FAIL_CODE, "请先审核营业执照，营业执照通过后才能审核经营许可证！");
        }
        authService.verifyAndUpdateAuth(transBusinessLicense, getLoginUser());
        return jsonView(SUCCESS_CODE, "道路运输经营许可证信息更新成功！");
    }


}
